package org.webscale.util.sqs;


import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.log4j.Logger;
import org.webscale.ApplicationController;
import org.webscale.ApplicationException;
import org.webscale.util.AWSCredential;

import com.xerox.amazonws.sqs2.Message;
import com.xerox.amazonws.sqs2.MessageQueue;
import com.xerox.amazonws.sqs2.SQSException;
import com.xerox.amazonws.sqs2.SQSUtils;

public class SQSListenerTimer extends TimerTask {
	static Logger log = Logger.getLogger(SQSListenerTimer.class);
	
	static int count =0;
	AWSCredential credentials ;
	String queueName;
	SQSListenerService sqsService;
	long timerTaskTimeInterval = 5000;
	static Timer timer = new Timer();
	
	public static void startListener(){
		SQSListenerTimer listener =(SQSListenerTimer) ApplicationController.instance().locateObject("sqsListenerTimer");
		
		Date rightNow = Calendar.getInstance().getTime();
	    timer.scheduleAtFixedRate(listener, rightNow, listener.getTimerTaskTimeInterval());
	}
	
	public static void stopTimer(){
		timer.cancel();
	}
	
	protected SQSListenerTimer(){
		super();
	}
	
	public void run() {
		log.debug("Checking message");
	    MessageQueue msgQueue;
		try {
			msgQueue = SQSUtils.connectToQueue(queueName, getCredentials().getAwsKey(), getCredentials().getAwsSecretKey());
	      
			boolean haveMoreMessageToRead = true;
			int messagesReadInThisCycle = 0;
			count ++;
	        while(haveMoreMessageToRead){
	        	Message msg = msgQueue.receiveMessage(); //TODO: check to see if you should use other methods available
	        	messagesReadInThisCycle++;
	        	
	        	if(msg != null){
	        		log.debug("msg NOT NULL TIMER COUNT =" + count + " CYCLE COUNT=" +messagesReadInThisCycle);
	        		sqsService.processMessage(msg ,msgQueue ); //This will return immediately as it will start a new thread
	        	}
	        	
	        	if(msg == null){ 
	        		
	        		//Case when no message in queue is when msg == null
	        		// OR if messages read in this cycle has reached the threadpool size go to next cycle because we do not want to block the application
	        		haveMoreMessageToRead = false;
	        		//Date rightNow = Calendar.getInstance().getTime();
	        	//	timer.schedule(this, rightNow, getTimerTaskTimeInterval());
	        		
	        	}
	        	
	        	if(messagesReadInThisCycle >= sqsService.getMaxPoolSize()){
	        		haveMoreMessageToRead = false;
	        		//Date rightNow = Calendar.getInstance().getTime();
	        		//timer.schedule(this, rightNow, 1000);
	        	}
	     }
		} catch (SQSException e) {
			log.error("Timer FAIL -" + e);
			throw new ApplicationException(e);
		}
	}
	
	public long getTimerTaskTimeInterval() {
		return timerTaskTimeInterval;
	}

	public void setTimerTaskTimeInterval(long timerTaskTimeInterval) {
		this.timerTaskTimeInterval = timerTaskTimeInterval;
	}

	public String getQueueName() {
		return queueName;
	}

	public void setQueueName(String queueName) {
		this.queueName = queueName;
	}

	public AWSCredential getCredentials() {
		return credentials;
	}

	public void setCredentials(AWSCredential credentials) {
		this.credentials = credentials;
	}

	public SQSListenerService getSqsService() {
		return sqsService;
	}

	public void setSqsService(SQSListenerService sqsService) {
		this.sqsService = sqsService;
	}
	
}
